/**
 * 
 */
package pe.bf.extranet.dao.impl;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.sql.DataSource;
import javax.sql.rowset.serial.SerialBlob;
import javax.sql.rowset.serial.SerialException;

import oracle.jdbc.OracleTypes;

import org.apache.log4j.Logger;

import pe.bf.base.dao.impl.BaseDAOImpl;
import pe.bf.base.types.OutParameter;
import pe.bf.domain.bean.Abono;
import pe.bf.domain.bean.Adjunto;
import pe.bf.domain.bean.Banco;
import pe.bf.domain.bean.Departamento;
import pe.bf.domain.bean.Distrito;
import pe.bf.domain.bean.Empleado;
import pe.bf.domain.bean.Empresa;
import pe.bf.domain.bean.Moneda;
import pe.bf.domain.bean.Perfil;
import pe.bf.domain.bean.Provincia;
import pe.bf.domain.bean.SolicitudAbono;
import pe.bf.domain.bean.TipoCuenta;
import pe.bf.domain.bean.TipoDocumento;
import pe.bf.domain.exceptions.DomainException;
import pe.bf.extranet.dao.MaestroDAO;
import pe.bf.extranet.dao.SolicitudAbonoDAO;

/**
 * @author mchavez
 * 
 */
public class MaestroDAOImpl extends BaseDAOImpl implements
		MaestroDAO {

	Logger logger = Logger.getLogger(MaestroDAOImpl.class);

 
	 static final String USP_LIS_TIPO_DOCUMENTO = "{call PGK_MAESTRO.USP_LIS_TIPO_DOCUMENTO(?)}";
	 static final String USP_LIS_DISTRITO = "{call PGK_MAESTRO.USP_LIS_DISTRITO(?)}";
	 static final String USP_LIS_EMPRESA = "{call PGK_MAESTRO.USP_LIS_EMPRESA(?)}";
	 static final String USP_LIS_MONEDA = "{call PGK_MAESTRO.USP_LIS_MONEDA(?)}";
	 static final String USP_LIS_TIPO_CUENTA = "{call PGK_MAESTRO.USP_LIS_TIPO_CUENTA(?)}";
	 static final String USP_LIS_PERFIL = "{call PGK_MAESTRO.USP_LIS_PERFIL(?)}";
	 static final String USP_LIS_BANCO = "{call PGK_MAESTRO.USP_LIS_BANCO(?)}";
	 static final String USP_LIS_DEPARTAMENTOS = "{call PGK_MAESTRO.USP_LIS_DEPARTAMENTOS(?)}";
	 static final String USP_LIS_PROVINCIAS = "{call PGK_MAESTRO.USP_LIS_PROVINCIAS(?,?)}";
	 static final String USP_LIS_DISTRITOS = "{call PGK_MAESTRO.USP_LIS_DISTRITOS(?,?)}";


	/**
	 * 
	 * @param dataSource
	 */
	public MaestroDAOImpl(DataSource dataSource) {
		super(dataSource);
	}
 
   
	
	
	@Override
	public List<TipoDocumento> findTipoDocumentos() throws DomainException {
		CallableStatement cal =invokeStoreProcedureCallable(USP_LIS_TIPO_DOCUMENTO ,new OutParameter(OracleTypes.CURSOR));
		List<TipoDocumento> listaTipoDocumento=new ArrayList();
		try{
			ResultSet resultSet=null;
			resultSet=(ResultSet)cal.getObject(1);
			while(resultSet.next()){
				TipoDocumento tipoDocumento= new TipoDocumento();
				tipoDocumento.setIdTipodocumento(resultSet.getLong(0));
				tipoDocumento.setDescripcion(resultSet.getString(1));
				tipoDocumento.setEstado(resultSet.getString(2));
				listaTipoDocumento.add(tipoDocumento);
			}
			return listaTipoDocumento;
		} catch (SQLException e) {
			e.printStackTrace();
//			logger.error(e, e.fillInStackTrace());
			throw new DomainException(e);
		}finally{
			try {
				cal.getConnection().close();
				cal.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		} 	
	}

	@Override
	public List<Distrito> findDistritos() throws DomainException {
		CallableStatement cal =invokeStoreProcedureCallable(USP_LIS_DISTRITO, new OutParameter(OracleTypes.CURSOR));
		List<Distrito> listaDistrito=new ArrayList();
		try{
			ResultSet resultSet=null;
			resultSet=(ResultSet)cal.getObject(1);
			while(resultSet.next()){
				Distrito distrito= new Distrito();
				distrito.setIdDistrito(resultSet.getLong(1));
				distrito.setDescripcion(resultSet.getString(2));
				distrito.setEstado(resultSet.getString(3));
//				distrito.setProvincia(resultSet.getString(4));
				listaDistrito.add(distrito);
			}
			return listaDistrito;
		} catch (SQLException e) {
			logger.error(e, e.fillInStackTrace());
			throw new DomainException(e);
		}finally{
			try {
				cal.getConnection().close();
				cal.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		} 
	}

	@Override
	public List<Empresa> findEmpresas() throws DomainException {
		CallableStatement cal =invokeStoreProcedureCallable(USP_LIS_EMPRESA, new OutParameter(OracleTypes.CURSOR));
		List<Empresa> listaEmpresa=new ArrayList();
		try{
			ResultSet resultSet=null;
			resultSet=(ResultSet)cal.getObject(1);
			while(resultSet.next()){
				Empresa empresa= new Empresa();
				empresa.setIdEmpresa(resultSet.getLong(1));
				empresa.setDireccion(resultSet.getString(2));
				empresa.setEstado(resultSet.getString(3));
				empresa.setNombres(resultSet.getString(4));
				empresa.setRuc(resultSet.getString(5));
				empresa.setTelefono1(resultSet.getString(6));
				empresa.setTelefono2(resultSet.getString(7));
				listaEmpresa.add(empresa);
			}
			return listaEmpresa;
		} catch (SQLException e) {
			logger.error(e, e.fillInStackTrace());
			throw new DomainException(e);
		}finally{
			try {
				cal.getConnection().close();
				cal.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		} 
	}

	@Override
	public List<Moneda> findMonedas() throws DomainException {
		CallableStatement cal =invokeStoreProcedureCallable(USP_LIS_MONEDA, new OutParameter(OracleTypes.CURSOR));
		List<Moneda> listaMoneda=new ArrayList();
		try{
			ResultSet resultSet=null;
			resultSet=(ResultSet)cal.getObject(1);
			while(resultSet.next()){
				Moneda moneda= new Moneda();
				moneda.setIdMoneda(resultSet.getLong(1));
				moneda.setDescripcion(resultSet.getString(2));
				moneda.setEstado(resultSet.getString(3));
				listaMoneda.add(moneda);
			}
			System.out.println("monedas  = listaMoneda " + listaMoneda.size() );
			return listaMoneda;
		} catch (SQLException e) {
			logger.error(e, e.fillInStackTrace());
			throw new DomainException(e);
		}finally{
			try {
				cal.getConnection().close();
				cal.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		} 
	}

	@Override
	public List<TipoCuenta> findTipoCuentas() throws DomainException {
		CallableStatement cal =invokeStoreProcedureCallable(USP_LIS_TIPO_CUENTA, new OutParameter(OracleTypes.CURSOR));
		List<TipoCuenta> listaTipoCuenta=new ArrayList();
		try{
			ResultSet resultSet=null;
			resultSet=(ResultSet)cal.getObject(1);
			while(resultSet.next()){
				TipoCuenta tipoCuenta= new TipoCuenta();
				tipoCuenta.setIdTipocuenta(Long.valueOf(resultSet.getString(1)));
				tipoCuenta.setDescripcion(resultSet.getString(2));
				tipoCuenta.setEstado(resultSet.getString(3));
				listaTipoCuenta.add(tipoCuenta);
			}
			return listaTipoCuenta;
		} catch (SQLException e) {
			logger.error(e, e.fillInStackTrace());
			throw new DomainException(e);
		}finally{
			try {
				cal.getConnection().close();
				cal.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}  	
	}
 
	@Override
	public List<Perfil> findPerfiles() throws DomainException {
		CallableStatement cal =invokeStoreProcedureCallable(USP_LIS_PERFIL, new OutParameter(OracleTypes.CURSOR));
		List<Perfil> listaPerfil=new ArrayList();
		try{
			ResultSet resultSet=null;
			resultSet=(ResultSet)cal.getObject(1);
			while(resultSet.next()){
				Perfil perfil= new Perfil();
				perfil.setIdPerfil(resultSet.getLong(1));
				perfil.setDescripcion(resultSet.getString(2)); 
				listaPerfil.add(perfil);
			}
			return listaPerfil;
		} catch (SQLException e) {
			logger.error(e, e.fillInStackTrace());
			throw new DomainException(e);
		}finally{
			try {
				cal.getConnection().close();
				cal.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}  	
	}
 
	@Override
	public List<Banco> findBancos() throws DomainException {
		CallableStatement cal =invokeStoreProcedureCallable(USP_LIS_BANCO, new OutParameter(OracleTypes.CURSOR));
		 ResultSet resultSet=null;
		 try{ 
		 resultSet = (ResultSet) cal.getObject(1);
		 
		List<Banco> lista=new ArrayList();
			while(resultSet.next()){
				Banco banco= new Banco();
				banco.setIdBanco(resultSet.getLong(1));
				banco.setDescripcion(resultSet.getString(2)); 
				lista.add(banco);
			}
			return lista;
		} catch (Exception e) {
			e.printStackTrace();
			throw new DomainException(e);
		}finally{
			try {
				cal.getConnection().close();
				cal.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}
	@Override
	public List<Departamento> findDepartamento() throws DomainException {
		CallableStatement cal =invokeStoreProcedureCallable(USP_LIS_DEPARTAMENTOS, new OutParameter(OracleTypes.CURSOR));
		 ResultSet resultSet=null;
		 try{ 
		 resultSet = (ResultSet) cal.getObject(1);
		 
		List<Departamento> lista=new ArrayList();
			while(resultSet.next()){
				Departamento objeto= new Departamento();
				objeto.setIdDepartamento(resultSet.getLong(1));
				objeto.setDescripcion(resultSet.getString(2)); 
				lista.add(objeto);
			}
			return lista;
		} catch (Exception e) {
			e.printStackTrace();
			throw new DomainException(e);
		}finally{
			try {
				cal.getConnection().close();
				cal.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}
	public List<Provincia> findProvincia(String codigo) throws DomainException {
		CallableStatement cal =invokeStoreProcedureCallable(USP_LIS_PROVINCIAS,codigo, new OutParameter(OracleTypes.CURSOR));
		 ResultSet resultSet=null;
		 try{ 
		 resultSet = (ResultSet) cal.getObject(2);
		 
		List<Provincia> lista=new ArrayList();
			while(resultSet.next()){
				Provincia objeto= new Provincia();
				objeto.setIdProvincia(resultSet.getLong(1));
				objeto.setDescripcion(resultSet.getString(2)); 
				lista.add(objeto);
			}
			return lista;
		} catch (Exception e) {
			e.printStackTrace();
			throw new DomainException(e);
		}finally{
			try {
				cal.getConnection().close();
				cal.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}
	public List<Distrito> findDistrito(String codigo) throws DomainException {
		CallableStatement cal =invokeStoreProcedureCallable(USP_LIS_DISTRITOS, codigo , new OutParameter(OracleTypes.CURSOR));
		 ResultSet resultSet=null;
		 try{ 
		 resultSet = (ResultSet) cal.getObject(2);
		 
		List<Distrito> lista=new ArrayList();
			while(resultSet.next()){
				Distrito objeto= new Distrito();
				objeto.setIdDistrito(resultSet.getLong(1));
				objeto.setDescripcion(resultSet.getString(2)); 
				lista.add(objeto);
			}
			return lista;
		} catch (Exception e) {
			e.printStackTrace();
			throw new DomainException(e);
		}finally{
			try {
				cal.getConnection().close();
				cal.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}

}
